/*
 * Copyright (C) 2011 Sherlock Downloader
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.sherlock.downloader.fetchers;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.sherlock.commons.download.FetcherException;
import org.sherlock.downloader.Download;
import org.sherlock.downloader.Download.Status;

/**
 * 
 * @author Sherlock Downloader
 */
public class HTTPFetcher extends Fetcher {

	private static final int MAX_BUFFER_SIZE = 102400;

	private HttpURLConnection connection;

	public HTTPFetcher(Download downloads) {
		super(downloads);
	}

	@Override
	public void run() {
		if (download.getStatus() == Status.READY) {
			download();
		}
		
		InputStream stream = null;

		try {
			stream = connection.getInputStream();
			int downloaded = download.getDownloaded();
			while (download.getStatus() == Status.DOWNLOADING) {
				byte buffer[];
				int size = download.getSize();

				if (size - downloaded > MAX_BUFFER_SIZE) {
					buffer = new byte[MAX_BUFFER_SIZE];
				} else {
					buffer = new byte[size - downloaded];
				}

				int read = stream.read(buffer);

				if (read == -1) {
					download.setStatus(Status.COMPLETE);
				} else {
					file.write(buffer, 0, read);
					downloaded += read;
					download.setDownloaded(downloaded);
					download.setStatus(Status.DOWNLOADING);
				}
			}
		} catch (IOException ex) {
			download.setStatus(Status.COMPLETE);
		} finally {
			try {
				file.close();
			} catch (IOException ex) {
			}
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException ex) {
				}
			}
		}
	}

	@Override
	public void connect() throws FetcherException {
		try {
			int downloaded = download.getDownloaded();

			URL url = download.getRemoteURL();
			connection = (HttpURLConnection) url.openConnection();
			connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
			connection.connect();

			if (connection.getResponseCode() / 100 != 2) {
				throw new FetcherException();
			}

			int contentLength = connection.getContentLength();
			if (contentLength < 1) {
				throw new FetcherException();
			} else {
				download.setSize(contentLength + downloaded);
			}
		} catch (IOException e) {
			throw new FetcherException();
		}
	}
}
